package com.utility.project.service.impl;

import cn.hutool.Hutool;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
import com.utility.project.common.base.ServiceException;
import com.utility.project.common.constants.YsConstant;
import com.utility.project.dto.CustomeUseAndTime;
import com.utility.project.entity.YsCustomer;
import com.utility.project.entity.YsMemberConfig;
import com.utility.project.mapper.YsCustomerMapper;
import com.utility.project.param.CustomerParam;
import com.utility.project.service.IYsCustomerService;
import com.utility.project.service.IYsMemberConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author yangzhiguo
 * @date 2024-06-13
 * @description 行业人才表
 */
@Service
@Slf4j
public class YsCustomerServiceImpl extends ServiceImpl<YsCustomerMapper, YsCustomer> implements IYsCustomerService {

    private static final Interner<String> customer_usage_intern = Interners.newWeakInterner();

    @Resource
    private IYsMemberConfigService ysMemberConfigService;

    @Override
    public YsCustomer queryYsCustomer(String username) {
        QueryWrapper<YsCustomer> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return baseMapper.selectOne(queryWrapper);
    }

    @Override
    public Boolean saveCustomer(CustomerParam param) {
        long size = this.list().stream().count();
        String username = param.getUsername();
        String phoneNumber = param.getPhoneNumber();
        String memberType = param.getMemberType();
        String nickName = param.getNickName();
        YsCustomer ysCustomer = this.queryYsCustomer(username);
        if (ysCustomer == null) {
            ysCustomer = new YsCustomer();
            ysCustomer.setUsername(username);
            if (StrUtil.isNotBlank(phoneNumber)) {
                ysCustomer.setPhoneNumber(phoneNumber);
            } else {
                String phone = String.format("%011d", size);
                ysCustomer.setPhoneNumber(phone);
            }
            ysCustomer.setMemberType(memberType);
            ysCustomer.setNickName(nickName);
            ysCustomer.setDelFlag(0);
            ysCustomer.setStatus(true);
            ysCustomer.setCreateBy("admin");
            ysCustomer.setCreateTime(new Date());
        } else {
            if (StrUtil.isNotBlank(phoneNumber)) {
                ysCustomer.setPhoneNumber(phoneNumber);
            }
            if (StrUtil.isNotBlank(memberType)) {
                ysCustomer.setMemberType(memberType);
            }
            if (StrUtil.isNotBlank(nickName)) {
                ysCustomer.setNickName(nickName);
            }
            ysCustomer.setUpdateBy("admin");
            ysCustomer.setUpdateTime(new Date());
        }
        return this.saveOrUpdate(ysCustomer);
    }

    @Override
    public Boolean updateCustomerStatus(CustomerParam param) {
        String username = param.getUsername();
        String memberType = param.getMemberType();
        YsCustomer ysCustomer = this.queryYsCustomer(username);
        Assert.notNull(ysCustomer, "会员信息不存在");
        ysCustomer.setMemberType(memberType);
        YsMemberConfig ysMemberConfig = ysMemberConfigService.queryConfig(memberType);
        Assert.notNull(ysMemberConfig, "会员等级信息不存在");
        Integer memberDays = ysMemberConfig.getMemberDays();
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, memberDays);
        ysCustomer.setEffectiveTime(calendar.getTime());
        ysCustomer.setUpdateBy("admin");
        ysCustomer.setMemberUsageTimes(ysMemberConfig.getUseNums());
        ysCustomer.setUpdateTime(new Date());
        return this.saveOrUpdate(ysCustomer);
    }

    @Override
    public Boolean abtainDailyFreeUser(String username) {
        YsCustomer ysCustomer = queryYsCustomer(username);
        Assert.notNull(ysCustomer, "会员信息不存在");
        YsMemberConfig ysMemberConfig = ysMemberConfigService.queryConfig(YsConstant.FREE_MEMBER);
        Assert.notNull(ysMemberConfig, "会员等级信息不存在");
        ysCustomer.setFreeUsageTimes(ysMemberConfig.getUseNums());
        ysCustomer.setDailyFreeuseAbtainTime(new Date());
        return this.saveOrUpdate(ysCustomer);
    }

    @Override
    public Boolean accessToUseOrNo(String username, Integer useNums) {
        YsCustomer ysCustomer = queryYsCustomer(username);
        Assert.notNull(ysCustomer, "会员信息不存在");
        Integer freeUsageTimes = ysCustomer.getFreeUsageTimes();
        Integer memberUsageTimes = ysCustomer.getMemberUsageTimes();
        freeUsageTimes = freeUsageTimes == null ? 0 : freeUsageTimes;
        memberUsageTimes = memberUsageTimes == null ? 0 : memberUsageTimes;
        if(memberUsageTimes == -1){
            return true;
        }
        int sum = freeUsageTimes + memberUsageTimes - useNums;
        if (sum < 0) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public Boolean reduceUseTimes(String username, Integer useNums) {
        log.info("{}用户，开始扣减使用次数", username);
        synchronized (customer_usage_intern) {
            YsCustomer ysCustomer = queryYsCustomer(username);
            Assert.notNull(ysCustomer, "会员信息不存在");
            Integer freeUsageTimes = ysCustomer.getFreeUsageTimes();
            Integer memberUsageTimes = ysCustomer.getMemberUsageTimes();
            if (freeUsageTimes != null && freeUsageTimes > 0) {
                freeUsageTimes = freeUsageTimes - useNums;
                if(freeUsageTimes < 0) {
                    freeUsageTimes = 0;
                }
                log.info("{}用户，扣除免费使用次数:{}，剩余次数：{}", username, useNums, freeUsageTimes);
            } else {
                if (memberUsageTimes != null) {
                    if (memberUsageTimes == -1) {
                        log.info("{}用户，vip不限次数，不做扣减计算", username);
                    } else if (memberUsageTimes > 0) {
                        memberUsageTimes = memberUsageTimes - useNums;
                        log.info("{}用户，扣除会员使用次数，剩余次数：{}", username, memberUsageTimes);
                    }

                }
            }
            ysCustomer.setFreeUsageTimes(freeUsageTimes);
            ysCustomer.setMemberUsageTimes(memberUsageTimes);
            return this.saveOrUpdate(ysCustomer);
        }
    }

    @Override
    public List<YsCustomer> queryCustomerByFreeUsage() {
        QueryWrapper<YsCustomer> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("free_usage_times", 0);
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public List<YsCustomer> queryInvalidCustomer() {
        //查询会员时间失效的会员列表
        QueryWrapper<YsCustomer> queryWrapper = new QueryWrapper<>();
        queryWrapper.le("effective_time", new Date());
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public Boolean queryDailyFreeUse(String username) {
        YsCustomer ysCustomer = queryYsCustomer(username);
        Assert.notNull(ysCustomer, "会员信息不存在");
        Date dailyFreeuseAbtainTime = ysCustomer.getDailyFreeuseAbtainTime();
        if (dailyFreeuseAbtainTime != null) {
            long betweenDay = DateUtil.betweenDay(dailyFreeuseAbtainTime, new Date(), true);
            if (betweenDay == 0) {
                return false;
            }
        }
        return true;
    }

    @Override
    public CustomeUseAndTime queryUseTimeAndValidTime(String username) {
        CustomeUseAndTime customeUseAndTime = new CustomeUseAndTime();
        YsCustomer ysCustomer = queryYsCustomer(username);
        Assert.notNull(ysCustomer, "会员信息不存在");
        Integer freeUsageTimes = Objects.isNull(ysCustomer.getFreeUsageTimes()) ? 0 : ysCustomer.getFreeUsageTimes();
        Integer memberUsageTimes = Objects.isNull(ysCustomer.getMemberUsageTimes()) ? 0 : ysCustomer.getMemberUsageTimes();
        if (freeUsageTimes == -1) {
            customeUseAndTime.setUsages(-1);
        } else {
            customeUseAndTime.setUsages(freeUsageTimes + memberUsageTimes);
        }
        Date effectiveTime = ysCustomer.getEffectiveTime();
        if (effectiveTime != null) {
            long validDays = DateUtil.between(new Date(), effectiveTime, DateUnit.DAY,false);
            if (validDays < 0) {
                validDays = 0l;
            }
            customeUseAndTime.setInValidTime(validDays);
        }
        return customeUseAndTime;
    }
}
